package basicobject

import (
	"github.com/pkg/errors"
	"yizhuoyan/go-study/pdfgo/handyio"
)

type Array struct {
	value []BasicObject
}

func (this *Array) Length() int {
	return len(this.value)
}
func (this *Array) Get(index int) BasicObject {
	return this.value[index]
}
func (this *Array) MustToStringArray() []string {
	var rst = make([]string, len(this.value))
	for i, one := range this.value {
		if oneName, is := one.(*Name); is {
			rst[i] = oneName.GetNameValue()
		} else {
			panic(errors.Errorf("Array[%v]不是Name类型", i))
		}
	}
	return rst
}

func (this *Array) MustGetInteger(index int) *Integer {
	if rst, is := this.value[index].(*Integer); is {
		return rst
	}
	if rst, is := this.value[index].(*Real); is {
		return &Integer{
			value: int(rst.value),
		}
	}
	panic(errors.Errorf("Array第%v个元素非Integer", index))
}
func (this *Array) MustGetReal(index int) *Real {
	if rst, is := this.value[index].(*Integer); is {
		return &Real{
			value: float64(rst.value),
		}
	}
	if rst, is := this.value[index].(*Real); is {
		return rst
	}
	panic(errors.Errorf("Array第%v个元素非Real", index))
}
func (this *Array) MustGetIndirectObjectReference(index int) *IndirectObjectReference {
	if rst, is := this.value[index].(*IndirectObjectReference); is {
		return rst
	}
	panic(errors.Errorf("Array第%v个元素非IndirectObjectReference", index))
}
func (this *Array) Serialize(w handyio.PdfRawWriter) error {
	w.WriteByte('[')
	for i, one := range this.value {
		if i > 0 {
			w.WriteByte(' ')
		}
		if err := one.Serialize(w); err != nil {
			return err
		}
	}
	w.WriteByte(']')
	return nil
}
func (this *Array) UnSerialize(r handyio.PdfRawReader) error {
	startAt := r.IndexCurrent()
	if !r.NextByteEquals('[') {
		return r.NotSupport("无开始[")
	}
	r.SkipNextWhiteSpaces()
	var rst = make([]BasicObject, 0, 10)
	for !r.NextByteEquals(']') {
		if obj, err := ReadrBasicObject(r); err != nil {
			_ = r.IndexMoveTo(startAt)
			return errors.Wrapf(err, "UnSerialize Array[%v]", len(rst))
		} else {
			rst = append(rst, obj)
		}
		r.SkipNextWhiteSpaces()
	}
	this.value = rst
	return nil
}
